<?php

namespace App\Http\Controllers\Admin;

use App\Models\Reservation;
use App\Models\ReservationApply;
use App\Models\ReservationSchedule;
use App\Models\ReservationSpecialSchedule;
use App\Validate\ReservationSpecialScheduleValidate;
use Illuminate\Support\Facades\DB;

/**
 * 文化配送类
 */
class ReservationSpecialScheduleController extends CommonController
{
    protected $model;
    protected $reservationApplyModel;
    protected $validate;

    public function __construct()
    {
        parent::__construct();

        $this->model = new ReservationSpecialSchedule();
        $this->reservationApplyModel = new ReservationApply();
        $this->validate = new ReservationSpecialScheduleValidate();
    }

    /**
     * 预约特殊日期排班列表
     * @param reservation_id int 预约id 0 为所有预约都支持的排版
     * @param page int 页数
     * @param limit int 限制条数
     * @param keywords string 搜索筛选
     * @param start_date date 开始时间
     * @param end_date date 结束时间
     */
    public function lists()
    {
        if (!$this->validate->scene('list')->check(request()->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $reservation_id = $this->request->reservation_id;
        $keywords = $this->request->keywords;
        $start_date = $this->request->start_date;
        $end_date = $this->request->end_date;
        $page = $this->request->page ? intval($this->request->page) : 1;
        $limit = $this->request->limit ? intval($this->request->limit) : 10;
        // if (!$reservation_id) {
        //     return $this->returnApi(201, "参数传递错误");
        // }
        $res = $this->model->lists($reservation_id, $keywords, $start_date, $end_date, $limit);
        if (empty($res['data'])) {
            return $this->returnApi(203, "无数据", "YES");
        }
        $reservationScheduleModel = new ReservationSchedule();
        foreach ($res['data'] as $key => $val) {
            $week_data = get_week($val['date']);
            $week = $week_data[0] == 0 ? 7 : (int)$week_data[0];
            $res['data'][$key]['week'] = $week_data[1];
            $normal_time = $reservationScheduleModel->getScheduleList($reservation_id, $week, ['id', DB::raw("GROUP_CONCAT(start_time,'~',end_time) as time")]);
            $res['data'][$key]['normal_time'] = !empty($normal_time) ? $normal_time[0]['time'] : null; //因为返回是一个数组，所以只取第一个元素
        }

        $res = $this->disPageData($res);
        $res['data'] = $this->addSerialNumber($res['data'], $page, $limit);

        return $this->returnApi(200, "查询成功", "YES", $res);
    }

    /**
     * 详情
     * @param $id date 排版id
     */
    public function detail()
    {
        if (!$this->validate->scene('detail')->check(request()->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        //日期转换标准格式
        $res = $this->model->detail($this->request->id);
        if (empty($res)) {
            return $this->returnApi(201, '参数错误');
        }
        return $this->returnApi(200, '查询成功', true, $res);
    }

    /**
     * 座位预约特殊日期排班新增
     * @param reservation_id int 预约id
     * @param date date  日期多个用,隔开   不能选择今天和今天之前的时间
     * @param name date  特殊排版名称
     * @param time 时间段 json格式数据，数组样式：[['start_time'=>'15:12:12' , 'end_time'=>'16:12:12'],['start_time'=>'15:12:12' , 'end_time'=>'16:12:12']]]  空数组表示不开放当前预约
     */
    public function add()
    {
        if (!$this->validate->scene('add')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $reservation_id = $this->request->reservation_id;
        $name = $this->request->name; //名称
        $date = $this->request->date; //日期
        $date_arr = explode(',', $date);
        $time = $this->request->time; //时间
        if (is_string($time)) {
            $time = json_decode($time, true);
        }
        //校验时间参数
        if (!is_array($time)) {
            return $this->returnApi(201, "时间段格式不正确");
        }
        //判断时间是否交叉
        if ($time) {
            $timeOver = compare_date($time);
            if (!$timeOver) {
                return $this->returnApi(201, "排版时间不能有交叉");
            }
        }
        $weekData = [];
        foreach ($date_arr as $key => $val) {
            //校验日期是否合规
            $date = date('Y-m-d', strtotime($val));
            if ($date == '1970-01-01') {
                return $this->returnApi(201, $date . "，日期格式不正确");
            }
            //不能添加当天的特殊日期
            if ($date <= date('Y-m-d')) {
                return $this->returnApi(201, $date . "，排版日期不能小于等于当前日期");
            }
            //校验日期是否存在
            $old_date = $this->model->where('reservation_id', $reservation_id)->where('date', $date)->first();
            if ($old_date) {
                return $this->returnApi(201, $date . "，新增日期已存在");
            }
            //先查看普通日期是否当前时间是否有预约
            $reservation_apply = $this->reservationApplyModel->getApplyInfo($reservation_id, [], $date, '=', [1, 3], 1);
            if (!empty($reservation_apply)) {
                return $this->returnApi(201, $date . "，当前添加的日期已有预约，请先处理后再添加");
            }
            $temp = [];
            //准备新增数据
            if ($time) {
                foreach ($time as $k => $v) {
                    $temp['reservation_id'] = $reservation_id;
                    $temp['date'] = $date;
                    $temp['name'] = $name;
                    $temp['start_time'] = $v['start_time'];
                    $temp['end_time'] = $v['end_time'];
                    $temp['create_time'] = date("Y-m-d H:i:s", time());
                    $weekData[] = $temp;
                }
            } else {
                $temp['reservation_id'] = $reservation_id;
                $temp['date'] = $date;
                $temp['name'] = $name;
                $temp['start_time'] = null;
                $temp['end_time'] = null;
                $temp['create_time'] = date("Y-m-d H:i:s", time());
                $weekData[] = $temp;
            }
        }
        $res = $this->model->insert($weekData);
        if ($res) {
            return $this->returnApi(200, "新增成功", 'YES');
        }
        return $this->returnApi(201, "新增失败");
    }

    /**
     * 座位预约特殊日期排班编辑
     * @param id int 排版id
     * @param reservation_id int 预约id
     * @param name int 特殊排版名称
     * @param time 时间段 json格式数据，数组样式：[['start_time'=>'15:12:12' , 'end_time'=>'16:12:12'],['start_time'=>'15:12:12' , 'end_time'=>'16:12:12']]]  空数组表示不开放当前预约
     */
    public function change()
    {
        if (!$this->validate->scene('change')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $special_schedule_info = $this->model->where('id', $this->request->id)->where('is_del', 1)->first();
        if (empty($special_schedule_info)) {
            return $this->returnApi(201, "特殊排版不存在");
        }
        if ($special_schedule_info->date <= date('Y-m-d')) {
            return $this->returnApi(201, "当前排版日期不允许修改");
        }

        $reservation_id = $special_schedule_info->reservation_id;
        $date = $special_schedule_info->date;
        $reservation_apply = $this->reservationApplyModel->getApplyInfo($reservation_id, [], $date, '=', [1, 3]);
        if (!empty($reservation_apply)) {
            return $this->returnApi(201, "当前修改的日期已有预约申请，请先处理后再修改");
        }

        //更新或者新增
        DB::beginTransaction();
        try {
            $data['id'] = $this->request->id;
            $data['reservation_id'] = $reservation_id;
            $data['name'] = $this->request->name;
            $data['date'] = $date;
            $data['time'] = $this->request->time;
            $this->model->change($data);
            DB::commit();
            return $this->returnApi(200, "编辑成功", 'YES');
        } catch (\Exception $e) {
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, '编辑失败');
        }
    }

    /**
     * 删除(将删除对应报名信息)
     * @param $id int 排版id
     */
    public function del()
    {
        if (!$this->validate->scene('del')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $id = $this->request->id;
        $res = $this->model->where('id', $id)->where('is_del', 1)->first();
        if (empty($res)) {
            return $this->returnApi(201, '参数错误');
        }
        $reservation_name = Reservation::where('id', $res->reservation_id)->where('is_del', 1)->value('name');

        $reservation_apply = [];
        if (!empty($reservation_name)) {
            //查询是否有人预约，如果已有人预约，禁止删除
            $reservation_apply = $this->reservationApplyModel->getApplyInfo($res->reservation_id, [], $res->date, '=', [1, 3], 2);
        }
        DB::beginTransaction();
        try {
            if ($reservation_apply) {
                $reservation_apply_ids = array_column($reservation_apply, 'id');
                $this->reservationApplyModel->whereIn('id', $reservation_apply_ids)->update(['status' => 2, 'change_time' => date('Y-m-d H:i:s')]);
                //消息推送
                foreach ($reservation_apply as $key => $val) {
                    $this->systemAdd("读者预约：申请失效", $val['user_id'], $val['account_id'], 34, intval($val['id']), '您申请的预约：【' . $reservation_name . '】排班已被管理员更改,您的预约已失效,请重新预约');
                }
            }
            //删除排版记录
            $this->model->where('reservation_id', $res->reservation_id)->where('date', $res->date)->update(['is_del' => 2, 'change_time' => date('Y-m-d H:i:s')]);
            DB::commit();
            return $this->returnApi(200, "删除成功", true);
        } catch (\Exception $e) {
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, "删除失败");
        }
    }
}
